﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HostTracker.Azure.Management;
using HostTracker.Azure.ProjectSettings;

namespace HostTracker.Azure.Tester
{
    class Program
    {
        static readonly int maxRetry = 5;
        static object sync = new object();
        static Dictionary<string, int> retryCounts = new Dictionary<string,int>();
        //static void OnResult(string reqId, CloudResponce<Microsoft.FSharp> resp) => {
        //            if (retryCounts.ContainsKey(reqId)) retryCounts.Remove(reqId);
        //            Console.WriteLine("Operation {0} succeeded", reqId);
        //        },

        static OperationResultHandlers consoleHandlers =
            OperationResultHandlers.FromFuncs(
                (reqId, resp) => {
                    if (retryCounts.ContainsKey(reqId)) retryCounts.Remove(reqId);
                    Console.WriteLine("Operation {0} ended", reqId);
                    if (resp.IsSuccess)
                    {
                        //var data = resp as CloudResponce<Microsoft.FSharp.Core.Unit, ServiceManagementError>.Success;
                        Console.WriteLine("Status: SUCCEED");
                    }
                    else
                    {
                        var fail = resp as CloudResponce<Microsoft.FSharp.Core.Unit, ServiceManagementError>.Fail;
                        Console.WriteLine("Cloud request failed. Reason {0}. Code {1}", fail.Item.data.Message, fail.Item.data.Code);
                    }
                },
                (fail) => Console.WriteLine("Operation failed on start. Reason: {0}, Code {1}", fail.data.Message, fail.data.Code),
                (ex) => Console.WriteLine("Exception rised on start: {0}", ex),
                (reqId, resp) => Console.WriteLine("{0} - operation in progress...", reqId),
                (reqId, fail) =>
                {
                    var count = maxRetry - 1;
                    if (retryCounts.ContainsKey(reqId))
                        count = retryCounts[reqId] - 1;
                    Console.WriteLine("Intermediate fail ({0}/{1})", count, maxRetry);
                    Console.WriteLine("\tReason: {0}, Code {1}", fail.data.Message, fail.data.Code);
                    retryCounts[reqId] = count;
                    return count > 0;
                },
                (reqId, ex) =>
                {
                    var count = maxRetry - 1;
                    if (retryCounts.ContainsKey(reqId))
                        count = retryCounts[reqId] - 1;
                    Console.WriteLine("Intermediate exception ({0}/{1})", count, maxRetry);
                    Console.WriteLine("\tDetails: {0}", ex);
                    retryCounts[reqId] = count;
                    return count > 0;
                });

        static void DeleteDeployment(string serviceName, DeploymentSlot slot)
        {
            Console.WriteLine("Deleting started");
            var task = DeploymentManagement.DeleteAsLongRunningTask(serviceName, slot, consoleHandlers);
            task.Wait();
        }

        static void CreateDeployment()
        {            
            Console.WriteLine("Start deployment creation");
            var deploymentCreation = new DeploymentCreation(true, true) 
                { 
                    Config = ServiceConfiguration.LoadFromFile(@"D:\HostTracker\trunk\HT.Azure\bin\Debug\app.publish\ServiceConfiguration.Cloud.cscfg"),
                    Label = "services",
                    Name = "services",
                    PackageUrl = @"http://htdeployment.blob.core.windows.net/root/HT.Azure.cspkg"
                };
            var task = DeploymentManagement.CreateAsLongRunningTask("HT", DeploymentSlot.Staging, deploymentCreation, consoleHandlers);
            task.Wait();
        }

        static void ChangeDeploymentState()
        {
            Console.WriteLine("Stoping deployment");
            var update = new DeploymentStatusUpdate(DeploymentStatus.Suspended);
            var task = DeploymentManagement.ChangeStatusAsLongRunningTask("HT", DeploymentSlot.Staging, update, consoleHandlers);
            task.Wait();
        }
        static void PrintAffinityGroups()
        {
            Console.WriteLine("Affinity groups");
            var task = AffinityGroupAndLocationManagement.GetAllTask();
            task.Wait();
            if (task.Result.IsSuccess)
            {
                var resp = task.Result as CloudResponce<AffinityGroups, ServiceManagementError>.Success;
                if (resp.Item.data.Count > 0)
                    foreach (var group in resp.Item.data)
                        Console.WriteLine("Label = {0}; Name = {1}\nDesc={2}\nLocation={3}", group.Label, group.Name, group.Desc, group.Location);
                else
                    Console.WriteLine("0 groups found");
            }
            else
            {
                var fail = task.Result as CloudResponce<AffinityGroups, ServiceManagementError>.Fail;
                Console.WriteLine("Cloud request failed. Reason {0}. Code {1}", fail.Item.data.Message, fail.Item.data.Code);
            }
        }
        static void Main(string[] args)
        {
            Console.WriteLine("Start");
            //CreateDeployment();
            //DeleteDeployment("HT", DeploymentSlot.Staging);
            //ChangeDeploymentState();
            PrintAffinityGroups();
            Console.WriteLine("End");
            Console.ReadKey();
        }
    }
}
